﻿using UnityEngine;
using System.Collections.Generic;
using System;

namespace GameBasic.BehaviorTree
{
    public class MultiActBhv : Bhv
    {
        internal MultiActSub[] subActions;

        public MultiActBhv() : base()
        {
            Init();
        }

        public MultiActBhv(string name) : base(name)
        {
            Init();
        }

        void Init()
        {
            OnStop(ResetSubActions);
            OnUpdate(UpdateSubActions);
        }

        void ResetSubActions()
        {
            if (subActions == null)
                return;

            int length = subActions.Length;
            for (int i = 0; i < length; i++)
            {
                MultiActSub subAct = subActions[i];
                subAct.progress = 0;
                subActions[i] = subAct;
            }
        }

        void UpdateSubActions()
        {
            if (subActions == null)
                return;

            float time = duration.Time;
            //bool stop = duration.ReachTarget();

            for (int i = 0, length = subActions.Length; i < length; i++)
            {
                MultiActSub subAct = subActions[i];
                float subActTime = time - subAct.startTime;
                float progressOld = subAct.progress;

                if (subActTime >= 0 && progressOld < 1)
                {
                    // execute only once
                    if (subAct.duration == 0)
                    {
                        subAct.progress = 1;

                        subAct.act(this, 1, RunStat.All);
                    }
                    else
                    {
                        // clamp[0, 1]
                        float progressNew = Mathf.Min(subActTime / subAct.duration, 1);
                        subAct.progress = progressNew;
                        RunStat e = new RunStat(progressOld, progressNew);

                        subAct.act(this, progressNew, e);
                    }
                    subActions[i] = subAct;
                }
            }
        }

        public void AddSubAct(MultiActSub subAct)
        {
            ArrayTools.Add(ref subActions, subAct);
        }

        public void AddSubAct(params MultiActSub[] subActs)
        {
            ArrayTools.Add(ref subActions, subActs);
        }

        public void ClearSubAct()
        {
            subActions = null;
        }

        public void SetSub(int index, float startTime)
        {
            MultiActSub sub = subActions[index];
            sub.startTime = startTime;

            subActions[index] = sub;
        }

        public void SetSub(int index, float startTime, float duration)
        {
            MultiActSub sub = subActions[index];
            sub.startTime = startTime;
            sub.duration = duration;

            subActions[index] = sub;
        }
    }
}